package com.wdcloud.netlibrary.request;

import com.wdcloud.netlibrary.dispatcher.CommonDispatcher;
import com.wdcloud.netlibrary.dispatcher.IDispatcher;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import okhttp3.Request;

/**
 * 请求信息组装
 * <p>
 */
public abstract class BaseRequest<T extends BaseRequest> implements IRequestBuild {

    /**
     * 不可重复的请求头
     */
    protected Map<String, String> headMap;

    /**
     * 可重复的请求头
     */
    protected Map<String, List<String>> addHeadMap;

    /**
     * 参数信息
     */
    protected Map<String, String> params;

    /**
     * 请求路径
     */
    protected String url;

    /**
     * 任务的唯一标示
     */
    protected Object tag;

    protected Request.Builder builder;


    /**
     * 添加请求头信息，重复添加会覆盖之前的信息
     *
     * @param key
     * @param value
     */
    public T header(String key, String value) {
        if (headMap == null) {
            headMap = new HashMap<>();
        }

        headMap.put(key, value);

        return (T) this;
    }

    /**
     * 添加请求头信息，重复添加会叠加，不会覆盖
     * @param key
     * @param value
     */
    public T addHeader(String key, String value) {
        if (addHeadMap == null) {
            addHeadMap = new HashMap<>();
        }
        if (addHeadMap.containsKey(key)) {
            List<String> values = addHeadMap.get(key);
            if (values == null) {
                throw new RuntimeException("参数组装错误");
            }
            values.add(value);
            addHeadMap.put(key, values);
        } else {
            List<String> values = new ArrayList<>();
            values.add(value);
            addHeadMap.put(key, values);
        }

        return (T) this;
    }

    /**
     * 添加参数
     *
     * @param key
     * @param value
     * @return
     */
    public T param(String key, String value) {
        if (params == null) {
            params = new HashMap<>();
        }
        params.put(key, value);
        return (T) this;
    }


    /**
     * 添加参数
     *
     * @param params
     * @return
     */
    public T params(Map<String, String> params) {
        if (params != null) {
            if (this.params == null) {
                this.params = new HashMap<>();
            }
            this.params.putAll(params);
        }
        return (T) this;
    }

    /**
     * 设置路径
     *
     * @param url
     * @return
     */
    public T url(String url) {
        this.url = url;
        return (T) this;
    }

    /**
     * 设置tag
     *
     * @param tag
     * @return
     */
    public T tag(Object tag) {
        this.tag = tag;
        return (T) this;
    }

    @Override
    public T addFile(Mapper<String, String, String> mapper) {
        return (T) this;
    }

    @Override
    public T addFile(List<Mapper<String, String, String>> mapper) {
        return (T) this;
    }

    @Override
    public T dir(String dir) {
        return (T) this;
    }

    @Override
    public T fileName(String fileName) {
        return (T) this;
    }


    @Override
    public T json(String json) {
        return (T) this;
    }

    @Override
    public T byteContent(byte[] bytes) {
        return (T) this;
    }

    /**
     * 组装头部信息
     */
    protected void buildHeader() {
        builder = new Request.Builder();
        if (headMap != null) {
            for (Map.Entry<String, String> entry : headMap.entrySet()) {
                builder.header(entry.getKey(), entry.getValue());
            }
        }
        if (addHeadMap != null) {
            for (Map.Entry<String, List<String>> entry : addHeadMap.entrySet()) {
                List<String> values = entry.getValue();
                for (String s : values) {
                    builder.addHeader(entry.getKey(), s);
                }
            }
        }
        if (tag != null) {
            builder.tag(tag);
        }
    }


    protected abstract void buildRequest();


    /**
     * 产生Call的调用者
     *
     * @return
     */
    public IDispatcher buildEvent() {
        buildHeader();
        buildRequest();
        return new CommonDispatcher(builder.build());
    }
}
